package tuding.android.bigplanettracks.maps;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import tuding.android.bigplanettracks.BigPlanet;
import tuding.android.bigplanettracks.R;
import tuding.android.bigplanettracks.maps.geoutils.GeoUtils;
import tuding.android.bigplanettracks.maps.geoutils.Point;
import tuding.android.bigplanettracks.maps.tuding.GMOT;
import tuding.android.bigplanettracks.maps.tuding.GMOffsetList;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.location.Location;
import android.util.Log;
import tuding.android.bigplanettracks.tracks.TrackAnalyzer;
//import android.widget.Toast;
import tuding.android.bigplanettracks.util.Preferences;

public class MarkerManager {

	public static final int MY_LOCATION_MARKER = 0;
	public static final int BOOKMARK_MARKER = 1;
	public static final int SEARCH_MARKER = 2;
	public static final int START_GREEN_MARKER = 3;
	public static final int END_GREEN_MARKER = 4;
	public static final int START_BLUE_MARKER = 5;
	public static final int START_OMIT_MARKER = 7;
	public static final int END_BLUE_MARKER = 6;
	public static final int ACTION_NOTES_MARKER = 8;
	public static final int ACTION_PHOTO_MARKER = 9;
	public static final int RECORDED_MARKER = 10;
	
	public static final int ACTION_TYPE_NOTES = 1;
	public static final int ACTION_TYPE_PHOTO = 2;
	
	public static int DrawMarkerForSearch = 0;
	public static int DrawMarkerOrTrack = 1;
	public static int DrawTrackFromDB = 2;
	public static int DrawMarkerForRecord = 3;
	
	//private HashMap<Integer,MarkerImage> images = new HashMap<Integer,MarkerImage>();
	public static HashMap<Integer,MarkerImage> images = new HashMap<Integer,MarkerImage>();
		
	// private List<Marker> markers = new ArrayList<Marker>();
	public static List<Marker> markers = new ArrayList<Marker>();
	public static List<Marker> markersG = new ArrayList<Marker>();
	public static List<Marker> savedTrackG = new ArrayList<Marker>();
	public static List<Marker> markersDB = new ArrayList<Marker>();
	public static List<Marker> markersRecord = new ArrayList<Marker>();
	
	//public static List<Marker> savedTrackGwoClearG = new ArrayList<Marker>();
	public static int IteratorG = 0;
	public static Location locA = null;
	public static Location locB = null;
	public static Location locC = null;
	public static int intvalBC = 0;
	public static boolean previous_marker_is_action_marker = false;
	//public static float totalDistance = 0;
	
	private Resources resources; 
	
	public MarkerManager(Resources resources){	
		this.resources = resources;
		images.put(MY_LOCATION_MARKER, new MarkerImage(decodeBitmap(R.drawable.person),24,39));
		images.put(BOOKMARK_MARKER, new MarkerImage(decodeBitmap(R.drawable.bookmark_marker),8,8));
		images.put(SEARCH_MARKER, new MarkerImage(decodeBitmap(R.drawable.location_marker),10,32));	
		images.put(START_BLUE_MARKER, new MarkerImage(decodeBitmap(R.drawable.ic_maps_blue_startpoint),17,36));	
		images.put(END_BLUE_MARKER, new MarkerImage(decodeBitmap(R.drawable.ic_maps_blue_endpoint),17,36));
		images.put(START_GREEN_MARKER, new MarkerImage(decodeBitmap(R.drawable.ic_maps_green_startpoint),17,36));	
		images.put(END_GREEN_MARKER, new MarkerImage(decodeBitmap(R.drawable.ic_maps_green_endpoint),17,36));
		images.put(START_OMIT_MARKER, new MarkerImage(decodeBitmap(R.drawable.ic_maps_startpoint_omit),17,36));	
		// add action marker image
		images.put(ACTION_NOTES_MARKER, new MarkerImage(decodeBitmap(R.drawable.notes36), 14, 35 ));
		images.put(ACTION_PHOTO_MARKER, new MarkerImage(decodeBitmap(R.drawable.images36), 14, 35 ));
		images.put(RECORDED_MARKER, new MarkerImage(decodeBitmap(R.drawable.spot), 8, 8));
	}
	
	public void clearMarkerManager() {
		markers.clear();
	}
	
	// вызывается при зуммировании, пересчет отступа и координат тайла всех маркеров
	public void updateCoordinates(int z){
		List<List<Marker>> allMarkerList = new ArrayList<List<Marker>>();
		allMarkerList.add(markers);
		allMarkerList.add(markersDB);
		allMarkerList.add(markersG);
		allMarkerList.add(savedTrackG);
		allMarkerList.add(markersRecord);
		for (int m = 0; m < allMarkerList.size(); m++) {
			for (Marker marker : allMarkerList.get(m)){
				Point tileXY = GeoUtils.toTileXY(marker.place.getLat(), marker.place.getLon(), z);
				Point offsetXY = GeoUtils.getPixelOffsetInTile(marker.place.getLat(), marker.place.getLon(), z);
				marker.offset = offsetXY;
				marker.tile.x = (int) tileXY.x;
				marker.tile.y = (int) tileXY.y;
				marker.tile.z = z;
			}
		}
	}
	
	// be attention, bookmarker has no effective lat lng value
	// org tile is left top corner one, but for markers we need tune it to the center
	public void addBookMarker(RawTile tile, int x, int y, int width, int height, long mkID) {
		Place place = new Place();
		place.setName("BOOKMARK");
		Marker marker = new Marker(place, images.get(BOOKMARK_MARKER), false, BOOKMARK_MARKER);
		marker.actionID = mkID;
		int newoffsetx = x - width/2;
		int newoffsety = y - height/2;
		int tilex = tile.x;
		int tiley = tile.y;
		int tilez = tile.z;
		int tiles = tile.s;
		
		while(newoffsetx <= -256) {
			tilex++;
			newoffsetx += 256;
		}
	
		while(newoffsety <= -256) {
			tiley++;
			newoffsety += 256;
		}
		
		marker.tile = new RawTile(tilex, tiley, tilez, tiles);
		marker.offset = new Point(newoffsetx, newoffsety);
		markers.add(marker);
		//Log.i("EVENT", "addBookMarker adding marker: "+tilex+" "+tiley+" "+tilez+" "+newoffsetx+" "+newoffsety);
	}
	
	
	public static void addMarker(Place place, int zoom, int trackType, int imageType, int actionType, long actionID) {
		Log.i("MARKER", "addMarker: imageType is "+imageType);
		if(actionType == 0 && actionID == 0) {
			addMarker(place, zoom, trackType, imageType);
		} else if(trackType == DrawMarkerOrTrack){ 
			Marker marker = new Marker(place, images.get(imageType), true, imageType, actionType, actionID);
			Log.i("MARKER", "place: "+place.getLat()+" "+place.getLon());
			updateParams(marker, zoom);
			if(BigPlanet.isGPSTracking){
				Log.i("MARKER", "adding action Marker tile is "+marker.tile.x+" "+marker.tile.y+" image type is "+imageType+" image is "+images.get(imageType));
				//markersG.add(marker); 
				try {
				    NoQualifyandSave(marker);
				} catch (Exception e) {
					e.printStackTrace();
				}
				try {
				    storeMarkersG();
				} catch (Exception e) {
					// out of bound e when get sublist
					e.printStackTrace();
				}
				BigPlanet.StoreInProgress = false;
			}
		} else if(trackType == DrawTrackFromDB){
			Marker marker_DB = new Marker(place, images.get(imageType), true, imageType, actionType, actionID);
			updateParams(marker_DB, zoom);
			// clear lastTime DB
			if(BigPlanet.isDBdrawclear){
				markersDB.clear();
				BigPlanet.isDBdrawclear = false;
			}
			markersDB.add(marker_DB);
		} else {
			Log.e("TRACK", "addMarker has unvalid parms");
		}
	}
	
	public static void addMarker(Place place, int zoom, int trackType, int imageType){
		/* trackType:
		 * 0 -> DrawMarkerForSearch, 
		 * 1 -> DrawMarkerOrTrack, 
		 * 2 -> DrawTrackFromDB
		 */
		boolean isGPS;
		if (trackType == DrawMarkerForSearch) {
			isGPS = false;
		} else {
			isGPS = true; 
		}
		
		if(trackType == DrawMarkerForRecord) {
			Marker marker = new Marker(place, images.get(imageType), isGPS, RECORDED_MARKER);
			updateParams(marker, zoom);
			markersRecord.clear(); // we only store one Record marker
			markersRecord.add(marker);
			//Log.i("Recording", "-->DrawMarkerForRecord");
		}
		
		else if(trackType == DrawMarkerForSearch){
			Marker marker = new Marker(place, images.get(imageType), isGPS, SEARCH_MARKER);
			updateParams(marker, zoom);
			markers.add(marker);
			//Log.i("EVENT", "addMarker::DrawMarkerForSearch adding marker");
		}
		else if(trackType == DrawMarkerOrTrack){
			Marker marker = new Marker(place, images.get(imageType), isGPS);
			updateParams(marker, zoom);
			if(BigPlanet.isGPSTracking){
				if (markersG.size()>0 && BigPlanet.appendingFlag == false){
					
					double lat = markersG.get(markersG.size()-1).place.getLat();
					double lon = markersG.get(markersG.size()-1).place.getLon();
					if (((marker.place.getLat() != lat) || (marker.place.getLon() != lon)) 
							&& (marker.place.getLat() != 0 && marker.place.getLon() != 0) ){
						// Panyf: filter out those markers in the same line with formers
						//if(!need_filterout(marker)) {
						//    markersG.add(marker);
						//}
						// need more power
						try {
						    NoQualifyandSave(marker);
						} catch (Exception e) {
							e.printStackTrace();
						}
						//markersG.add(marker);
					} 
				}else{
					// filter out currentLocationBeforeRecording
					if(BigPlanet.appendingFlag == true) BigPlanet.appendingFlag = false;
					Location location = BigPlanet.currentLocationBeforeRecording;
					if (location != null) {
						double lat = location.getLatitude();
						double lon = location.getLongitude();
						//if (((marker.place.getLat() != lat) || (marker.place.getLon() != lon)) // because place is offset-fixed
						if (((marker.place.getLocation().getLatitude() != lat) || (marker.place.getLocation().getLongitude() != lon))
								&& (marker.place.getLat() != 0 && marker.place.getLon() != 0) ) {
							markersG.add(marker);
							BigPlanet.currentLocationBeforeRecording = null;
						}
					}
				}
				
				// handle store the markersG into SDcard
				try {
				    storeMarkersG();
				} catch (Exception e) {
					// out of bound e when get sublist
					e.printStackTrace();
				}
			}
			
			//Log.i("TRACK", "onLocationChanged StoreInProgress is set to false");
			BigPlanet.StoreInProgress = false;
			
			
			
			
			Iterator<Marker> it = markers.iterator();
			while(it.hasNext()){
				Marker m = it.next();
				if(m.isGPS){
					it.remove();
					//Log.i("EVENT", "addMarker::DrawMarkerForSearch removing marker");
				}
			}
			//if(!BigPlanet.isGPSTracking){
				if(markers.size()>0){
					double lat = markers.get(0).place.getLat();
					double lon = markers.get(0).place.getLon();
					if ((marker.place.getLat() != lat) || (marker.place.getLon() != lon)){
						markers.add(marker);
						//Log.i("EVENT", "addMarker::1 adding marker");
					}	
				}else{
					markers.add(marker);
					//Log.i("EVENT", "addMarker::2 adding marker");
				}
			//}
		}
		else if(trackType == DrawTrackFromDB){
			Marker marker_DB = new Marker(place, images.get(imageType), isGPS);
			updateParams(marker_DB, zoom);
			// clear lastTime DB
			if(BigPlanet.isDBdrawclear){
				markersDB.clear();
				BigPlanet.isDBdrawclear = false;
			}
			markersDB.add(marker_DB);
		}
	}
	

	private static synchronized void NoQualifyandSave(Marker marker) {
		markersG.add(marker);
	}
	
	private static synchronized void QualifyandSave(Marker marker) {
		final int markersGsize = markersG.size();
		//Log.i("TRACK","new marker is coming: markersGsize: "+markersGsize);
		
		if(markersGsize < 2) { // first two marker will be enqueue directly
			markersG.add(marker);
		}
		else {
			if(markersGsize == 2 && locA == null && locB == null) { // check null to secure correctness when the third marker is not stored
			    locA = markersG.get(0).place.getLocation();
			    locB = markersG.get(1).place.getLocation();
			    Log.i("TRACK","locA and locB is assigned!");
			}
			
			locC = marker.place.getLocation();
			if(    intvalBC > 5 
				|| marker.actionType != 0
				|| previous_marker_is_action_marker == true // otherwise the actionmarker maybe delete later
		      //|| marker.place.getLocation().getSpeed() <= 3
				) { 
				Log.i("MARKER", " add a new marker "+marker.place.getLat()+" "+marker.place.getLon());
				intvalBC = 0;
				locA = locB;
				locB = locC;
				markersG.add(marker);
				previous_marker_is_action_marker = marker.actionType != 0 ? true : false; 
			} else if(TrackAnalyzer.isClosing(locA, locB, locC, 0.2)) {
				Log.i("TRACK","Found one marker which is not qulified to be record!!! intvalBC: "+intvalBC);
				markersG.remove(markersGsize-1);
				markersG.add(marker);
				intvalBC++;
			} else {
				Log.i("TRACK", "Add a normal qualified marker into markersG!");
				intvalBC = 0;
				locA = locB;
				locB = locC;
				markersG.add(marker);
			}
		}
		
		
		
	}
	
	public static boolean removeMarker(List<Marker> markers, int actionType, long actionID) {
		boolean rc = false;
		for(int i=0; i<markers.size(); i++) {
			Marker marker = markers.get(i); 
			if(marker.actionType == actionType && marker.actionID == actionID) {
				markers.remove(i);
				rc = true;
				break;
			}
		}
		return rc;
	}
	
	public static void updateParams(Marker marker, int zoom){
		Point tileXY = GeoUtils.toTileXY(marker.place.getLat(), marker.place.getLon(), zoom);
		RawTile mTile = new RawTile((int)tileXY.x, (int)tileXY.y, zoom, -1);
		//marker.tile = mTile;
		//Log.i("EVENT", "Update an  marker parms: "+mTile.x+" "+mTile.y+" "+mTile.z);
		Point offset = GeoUtils.getPixelOffsetInTile(marker.place.getLat(), marker.place.getLon(), zoom);
		//marker.offset = offset;
		
		if(Preferences.getSourceId() <= 2) {
		    marker.GMOffset = getGMOffset(mTile);
			Log.i("LL", "org offset: "+offset.x+" "+offset.y+" tile: "+mTile.x+" "+mTile.y+" "+mTile.z);
			offset.x += marker.GMOffset.x;
			offset.y += marker.GMOffset.y;
			Log.i("OFFSET2", "offset: "+offset.x+" "+offset.y);
			while (offset.x > 256) {
				mTile.x ++;
				offset.x -= 256;
			} 
			while (offset.x < 0) {
				mTile.x --;
				offset.x += 256;
			}
			while (offset.y > 256) {
				mTile.y ++;
				offset.y -= 256;
			} 
			while (offset.y < 0) {
				mTile.y --;
				offset.y += 256;
			}
		} 
		marker.tile = mTile;
		marker.offset = offset;
		Log.i("LL", "new offset: "+offset.x+" "+offset.y+" tile: "+mTile.x+" "+mTile.y+" "+mTile.z);
	}
	
	public static android.graphics.Point getGMOffset(RawTile tile) {
		android.graphics.Point rc = new android.graphics.Point(0,0);
		if(tile.z > 12) return rc; // when the zoom is too large, no need for offset fix
		int rcX = 0; 
		int rcY = 0;
		int index = GMOffsetList.indexOfTile(tile);
		if(index != -1) { 
			rc = GMOffsetList.getOffset(index);
			Log.i("OFFSET2","Find in cache");
			rcX = rc.x;
			rcY = rc.y;
		} else {
			GMOT gmot = new GMOT();
			rc = gmot.getOffsetByTileNum(tile);
			rcX = rc.x;
			rcY = rc.y;
			Log.w("OFFSET2","Not find in cache");
			gmot.close();
		}
		// process for current zoom level
		//Log.i("OFFSET", "MarkerManager getGMOffset 1: "+rcX+" "+rcY);
		if(3>=tile.z) {
			rcX = rcX << (3-tile.z);
			rcY = rcY << (3-tile.z);
		} else {
			rcX = rcX >> (tile.z-3);
			rcY = rcY >> (tile.z-3);
		}
		//Log.i("OFFSET", "MarkerManager getGMOffset: "+rcX+" "+rcY);
		return new android.graphics.Point(rcX, rcY);
	}
	
	public void updateBookMarker(Marker marker, int zoom) {
		//Log.i("EVENT", "Org marker info: x: "+marker.tile.x+ " y: "+marker.tile.y+" z:"+marker.tile.z+" offsetX: "+marker.offset.x+" offsetY: "+marker.offset.y);
		float currentZoomX = (float) (marker.tile.x * 256 - marker.offset.x); 
		float currentZoomY = (float) (marker.tile.y * 256 - marker.offset.y);
		float nextZoomX = (float) (currentZoomX * (Math.pow(2, (marker.tile.z-zoom))));
		float nextZoomY = (float) (currentZoomY * (Math.pow(2, (marker.tile.z-zoom))));
		marker.tile.x = (int) Math.floor(nextZoomX / 256);
		marker.tile.y = (int) Math.floor(nextZoomY / 256);
		marker.tile.z = zoom;
		marker.offset.x = marker.tile.x * 256 - nextZoomX;
		marker.offset.y = marker.tile.y * 256 - nextZoomY;
		//Log.i("EVENT", "Then marker info: x: "+marker.tile.x+ " y: "+marker.tile.y+" z:"+marker.tile.z+" offsetX: "+marker.offset.x+" offsetY: "+marker.offset.y);
		
	}
	
	public void updateAll(int zoom){
		for(Marker marker : markers){
			// add special case for those donot need place field, like bookmark
			if(marker.place.getName() != "BOOKMARK") {
			    updateParams(marker, zoom);
			    //Log.i("EVENT", "Update an none-Bookmark marker");
			} else {
				//Log.i("EVENT", "An BOOKMARK marker");
				updateBookMarker(marker, zoom);
			}
		}
		for(Marker marker : markersG){
			updateParams(marker, zoom);
		}
		for(Marker saveTrack_G : savedTrackG){
			updateParams(saveTrack_G, zoom);
		}
		for(Marker marker_DB : markersDB){
			updateParams(marker_DB, zoom);
		}
		for(Marker marker_Record : markersRecord) {
			updateParams(marker_Record, zoom);
		}
	}
	
	public List<Marker> getMarkers(int x, int y, int z){
		List<Marker> result = new ArrayList<Marker>();
		for(Marker marker:markers){
			if(marker.tile.x == x && marker.tile.y == y && marker.tile.z == z){
				result.add(marker);
			}
		}
		return result;
	}
	
	public List<Marker> getGMarkers(int x, int y, int z){
		List<Marker> result = new ArrayList<Marker>();
		for(Marker marker:markersG){
			if(marker.actionType != 0)
			if(marker.tile.x == x && marker.tile.y == y && marker.tile.z == z){
				result.add(marker);
			}
		}
		return result;
	}
	
	public List<Marker> getSavedGMarkers(int x, int y, int z){
		List<Marker> result = new ArrayList<Marker>();
		for(Marker marker:savedTrackG){
			if(marker.actionType != 0)
			if(marker.tile.x == x && marker.tile.y == y && marker.tile.z == z){
				result.add(marker);
			}
		}
		return result;
	}
	
	public List<Marker> getMarkersRecord(int x, int y, int z){
		List<Marker> result = new ArrayList<Marker>();
		for(Marker marker:markersRecord){
			if(marker.tile.x == x && marker.tile.y == y && marker.tile.z == z){
				result.add(marker);
				//Log.i("Recording", "-->getMarkersRecord");
			}
		}
		return result;
	}
	
	
	public List<Marker> getDBMarkers(int x, int y, int z){
		List<Marker> result = new ArrayList<Marker>();
		for(Marker marker:markersDB){
			if(marker.actionType != 0)
			if(marker.tile.x == x && marker.tile.y == y && marker.tile.z == z){
				result.add(marker);
			}
		}
		return result;
	}
	
	public boolean isDrawingMarkerG(int x, int y, int z, Marker marker) {
		boolean result = false;
		if (marker.tile.x == x && marker.tile.y == y && marker.tile.z == z) {
			result = true;
		}
		return result;
	}
	
	public void saveMarkerGTrack() {
		savedTrackG.clear();
		Log.i("TRACK","   in saveMarkerGTrack: markersG.size():"+markersG.size());
		for (int i=0; i<markersG.size(); i++) {
			savedTrackG.add(markersG.get(i));
		}
		Log.i("TRACK","   in saveMarkerGTrack: savedTrackG.size:"+savedTrackG.size());
		markersG.clear();
	} 
	
	// list operator will be quite slow
	/*
	private void saveMarkerGTrackwoClearG() {
		savedTrackGwoClearG.clear();
		for (int i=IteratorG; i<markersG.size(); i++) {
			savedTrackGwoClearG.add(markersG.get(i));
		}
		IteratorG = markersG.size();
	}*/
	
	public static synchronized void storeMarkersG() {
		Log.i("MARKER","markersG.size:"+markersG.size()+" IteratorG:"+IteratorG+" ");
		if(markersG.size() - IteratorG >= BigPlanet.STORE_THRESHOLD) {
			//saveMarkerGTrackwoClearG();
			try {
				// store sd and release some memory for more markers
			    BigPlanet.DBAdapter.open();
			    //BigPlanet.DBAdapter.insertNewMarker(BigPlanet.currentTrackID, getLocationList(savedTrackGwoClearG));
			    //BigPlanet.DBAdapter.insertNewMarker(BigPlanet.currentTrackID, getLocationList(markersG.subList(IteratorG, markersG.size())));
			    BigPlanet.DBAdapter.insertNewActionMarkerList(BigPlanet.currentTrackID, markersG.subList(IteratorG, markersG.size()));
			    Log.i("MARKER", "storeMarkersG insert actionMarker list: TrackID "+BigPlanet.currentTrackID+" IteratorG "+IteratorG+" markersG.size"+markersG.size());
			    BigPlanet.DBAdapter.updateTrack(BigPlanet.currentTrackID, 2); // 2 means need update stat : measureVersion
			    
			    // e.g. if the markers num is more than 100, then release 20%
				if(markersG.size() > BigPlanet.CURRENT_MAX_MARKER_NUM) {
					for(int i=0; i<BigPlanet.SHOW_MAX_MARKER_NUM; i++){
						markersG.remove(0);
						Log.i("MARKER", "--- Deleting marker "+i+" "+markersG.get(0).place.getLat()+" "+markersG.get(0).place.getLon());
					}
					BigPlanet.OMIT_MARKERS_FLAG = true;
				}
				
			    IteratorG = markersG.size();
			    //savedTrackGwoClearG.clear();
			} catch (Exception e) {
				e.printStackTrace();
				Log.e("TRACK", "Cannot store marker into SD!");
			}
			
			// it may be not a good idea of using thread in such perf critical path
			/*
			new Thread() {
				@Override
				public void run() {
					try {
						//Log.i("TRACK","Iterator:"+IteratorG);
						//Location firstLoc = markersG.get(0).place.getLocation();
						//Location lastLoc = markersG.get(IteratorG-1).place.getLocation();
						//Location currLoc = markersG.get(IteratorG-BigPlanet.STORE_THRESHOLD).place.getLocation();
						//final long totalTime = lastLoc.getTime() - firstLoc.getTime();
						//Log.i("TRACK","lastLoc.getTime():"+lastLoc.getTime()+" recordingTime"+BigPlanet.recordingTime);
						//totalDistance += lastLoc.distanceTo(currLoc);
						Log.i("TRACK", "BEGIN store to SD!");
						BigPlanet.DBAdapter.open();
						//Log.i("TRACK","savedTrackGwoClearG size is "+savedTrackGwoClearG.size());
					    BigPlanet.DBAdapter.insertNewMarker(BigPlanet.currentTrackID, getLocationList(savedTrackGwoClearG));
					    BigPlanet.DBAdapter.updateTrack(BigPlanet.currentTrackID, 2); // 2 means need update stat
					    Log.i("TRACK", "END store to SD!");
					} catch (Exception e) {
						e.printStackTrace();
						Log.e("TRACK", "Cannot store marker into SD!");
					}
				}
			}.start();*/
		}
		//Log.i("TRACK", "onLocationChanged StoreInProgress is set to false");
		//BigPlanet.StoreInProgress = false;
	}
	/*
	public void saveMarkerGTrackwoClearG_last() {
		savedTrackGwoClearG.clear();
		for (int i=IteratorG; i<savedTrackG.size(); i++) {
			savedTrackGwoClearG.add(savedTrackG.get(i));
		}
		IteratorG = savedTrackG.size();
	}*/
	
	public synchronized void storeMarkersG_block() {
		if(savedTrackG.size() - IteratorG > 0) {
			//saveMarkerGTrackwoClearG_last();
			try {
				BigPlanet.DBAdapter.open();
			    //BigPlanet.DBAdapter.insertNewMarker(BigPlanet.currentTrackID, getLocationList(savedTrackG.subList(IteratorG, savedTrackG.size())));
				Log.i("MARKER","storeMarkersG_block for action markers/ markersG size is "+markersG.size());
				BigPlanet.DBAdapter.insertNewActionMarkerList(BigPlanet.currentTrackID, savedTrackG.subList(IteratorG, savedTrackG.size()));
			    //IteratorG = markersG.size();
				IteratorG = savedTrackG.size(); // to avoid this func is called in BP onDesctroy() again
			    BigPlanet.DBAdapter.updateTrack(BigPlanet.currentTrackID, 2); // 2 means need update stat : measureVersion
			} catch (Exception e) {
				Log.e("TRACK", "Cannot store marker into SD !");
			}
		}
	}
	
	public boolean clearSavedTracksG(){
		if(!BigPlanet.isGPSTracking){
			savedTrackG.clear();
			BigPlanet.isGPSTrackSaved = false;
			return true;
		}else{
			return false;
		}
	}
	
	public void clearMarkersDB(){
		BigPlanet.OMIT_MARKERS_FLAG = false;
		markersDB.clear();
	}
	
	public static ArrayList<Location> getLocationList(List<Marker> markerList){
		ArrayList<Location> list = new ArrayList<Location>();
		for (int i=0; i<markerList.size(); i++) {
			Location location = markerList.get(i).place.getLocation();
			if (location != null)
				list.add(location);
			else Log.i("TRACK","A null point");
		}
		return list;
	}
	
	public static ArrayList<Location> getLocationList(List<Marker> markerList, int startpoint){
		ArrayList<Location> list = new ArrayList<Location>();
		for (int i=startpoint; i<markerList.size(); i++) {
			Location location = markerList.get(i).place.getLocation();
			if (location != null)
				list.add(location);
		}
		return list;
	}
	
	private Bitmap decodeBitmap(int resourceId){
		return BitmapFactory.decodeResource(resources, resourceId);
	}
}
	



